﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using org.pdfbox.pdmodel;
using org.pdfbox.util;
using System.Text.RegularExpressions;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
namespace PdfContentSelect
{
    public partial class Form1 : Form
    {
        private string folderPath;
        private List<string> historyPath;
        public Form1()
        {
            InitializeComponent();
            folderPath = "";
            historyPath = new List<string>();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() != DialogResult.OK)
                return;
            comboBox1.Items.Insert(0,fbd.SelectedPath);
            comboBox1.SelectedIndex = 0;
        }

        private List<string> GetAllFilePath(string path)
        {
            List<string> AllPath = new List<string>();
            foreach (string directoryName in Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly))
            {
                AllPath.AddRange(GetAllFilePath(directoryName));
            }

            foreach (string fileName in Directory.GetFiles(path, "*.pdf"))
            {
                AllPath.Add(fileName);
            }
            return AllPath;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            folderPath = comboBox1.Text;
            if (folderPath == "" || textBox2.Text == "")
                return;

            if (historyPath.Contains(folderPath))
            {
                historyPath.Remove(folderPath);
                historyPath.Insert(0, folderPath);
            }
            else
            {
                if (historyPath.Count <= 4)
                {
                    historyPath.Insert(0, folderPath);
                }
                else if (historyPath.Count > 4)
                {
                    historyPath.RemoveAt(4);
                    historyPath.Insert(0, folderPath);
                }
            }
            List<string> AllFilePath = GetAllFilePath(folderPath);
            toolStripProgressBar1.Maximum = AllFilePath.Count;
            toolStripProgressBar1.Value = 0;
            toolStripStatusLabel1.Text = "共" + AllFilePath.Count + "个文件，正在处理第" + toolStripProgressBar1.Value + "个文件。";
            List<PDFResult> lists = new List<PDFResult>();
            string[] keywords = textBox2.Text.Split(',');
            Regex[] regs = new Regex[keywords.Length];
            bool[] matchResult = new bool[keywords.Length];
            for (int i = 0; i < keywords.Length; i++)
            {
                regs[i] = new Regex(keywords[i]);
            }
            DateTime t1 = DateTime.Now;
            foreach (string file in AllFilePath)
            {
                Application.DoEvents();
                for (int i = 0; i < keywords.Length; i++)
                {
                    matchResult[i] = false;
                }
                try
                {
                    #region pdfbox有bug，不如itextsharp
                    //PDDocument doc = PDDocument.load(file);
                    //PDFTextStripper stripper = new PDFTextStripper();
                    //string txt = stripper.getText(doc);
                    //if (reg.IsMatch(txt))
                    //{
                    //    lists.Add(new PDFResult(file, true));
                    //}
                    #endregion

                    #region itextsharp
                    PdfReader pdfReader = new PdfReader(file);
                    int numberOfPages = pdfReader.NumberOfPages;

                    for (int i = 1; i <= numberOfPages; ++i)
                    {
                        //byte[] bufferOfPageContent = pdfReader.GetPageContent(i);
                        //string text= System.Text.Encoding.UTF8.GetString(bufferOfPageContent);
                        ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
                        string text = PdfTextExtractor.GetTextFromPage(pdfReader, i, strategy);
                        PdfObject pobj = pdfReader.GetPdfObject(i);
                        text = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(text)));
                        //text.Append(currentText);

                        if (IsMatch(regs, text, matchResult))
                        {
                            lists.Add(new PDFResult(file, true));
                            break;
                        }
                    }
                    pdfReader.Close();

                    #endregion


                }
                catch (Exception ex)
                {
                    lists.Add(new PDFResult(file, false));
                    toolStripProgressBar1.Value++;
                    toolStripStatusLabel1.Text = "共" + AllFilePath.Count + "个文件，正在处理第" + toolStripProgressBar1.Value + "个文件。";
                    continue;
                }


                toolStripProgressBar1.Value++;
                toolStripStatusLabel1.Text = "共" + AllFilePath.Count + "个文件，正在处理第" + toolStripProgressBar1.Value + "个文件。";
            }
            DateTime t2 = DateTime.Now;
            MessageBox.Show((t2 - t1).ToString());
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            toolStripStatusLabel1.Text = "";
            QueryResult form = new QueryResult(lists);
            //form.Owner = this;
            form.Show();

            lists.Clear();
            AllFilePath.Clear();
            //MessageBox.Show("查找完成。");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            folderPath = comboBox1.Text;
            if (folderPath == "" || textBox2.Text == "")
                return;

            if (historyPath.Contains(folderPath))
            {
                historyPath.Remove(folderPath);
                historyPath.Insert(0, folderPath);
            }
            else
            {
                if (historyPath.Count <= 4)
                {
                    historyPath.Insert(0, folderPath);
                }
                else if (historyPath.Count > 4)
                {
                    historyPath.RemoveAt(4);
                    historyPath.Insert(0, folderPath);
                }
            }

            List<string> AllFilePath = GetAllFilePath(folderPath);
            toolStripProgressBar1.Maximum = AllFilePath.Count;
            toolStripProgressBar1.Value = 0;
            toolStripStatusLabel1.Text = "共" + AllFilePath.Count + "个文件，正在处理第" + toolStripProgressBar1.Value + "个文件。";
            List<PDFResult> lists = new List<PDFResult>();
            string[] keywords = textBox2.Text.Split(',');
            Regex[] regs = new Regex[keywords.Length];

            for (int i = 0; i < keywords.Length; i++)
            {
                regs[i] = new Regex(keywords[i]);
            }
            DateTime t1 = DateTime.Now;
            try
            {
                Parallel.ForEach(AllFilePath, (file, ParallelLoopState) =>
                {
                    Application.DoEvents();
                    bool[] matchResult = new bool[keywords.Length];
                    for (int i = 0; i < keywords.Length; i++)
                    {
                        matchResult[i] = false;
                    }


                    #region itextsharp
                    PdfReader pdfReader = new PdfReader(file);
                    int numberOfPages = pdfReader.NumberOfPages;

                    for (int i = 1; i <= numberOfPages; ++i)
                    {
                        //byte[] bufferOfPageContent = pdfReader.GetPageContent(i);
                        //string text= System.Text.Encoding.UTF8.GetString(bufferOfPageContent);
                        ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
                        string text = PdfTextExtractor.GetTextFromPage(pdfReader, i, strategy);

                        text = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(text)));
                        //text.Append(currentText);

                        if (IsMatch(regs, text, matchResult))
                        {
                            lists.Add(new PDFResult(file, true));
                            break;
                        }
                    }
                    pdfReader.Close();

                    #endregion
                    //this.Invoke(new MethodInvoker(() => toolStripProgressBar1.Value++));

                    //toolStripStatusLabel1.Text = "共" + AllFilePath.Count + "个文件，正在处理第" + toolStripProgressBar1.Value + "个文件。";
                });

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n并行错误，请使用串行查找。");
                return;
            }
            DateTime t2 = DateTime.Now;
            MessageBox.Show((t2 - t1).ToString());
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            toolStripStatusLabel1.Text = "";
            QueryResult form = new QueryResult(lists);
            form.ShowDialog();

            lists.Clear();
            AllFilePath.Clear();
        }

        private bool IsMatch(Regex[] regs, string text, bool[] matchRes)
        {
            for (int i = 0; i < regs.Length; i++)
            {
                if (matchRes[i] == false && regs[i].IsMatch(text))
                {
                    matchRes[i] = true;
                }
            }
            foreach (bool item in matchRes)
            {
                if (item == false)
                {
                    return false;
                }
            }

            return true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!File.Exists("HistoryPath.cache"))
                return;
            StreamReader sr = new StreamReader("HistoryPath.cache");
            string str = string.Empty;
            while ((str = sr.ReadLine()) != null)
            {
                historyPath.Add(str);
                comboBox1.Items.Add(str);
            }
            sr.Close();
        }

        private void SaveHistoryPath()
        {
            if(historyPath.Count==0)
                return;
            StreamWriter sw = new StreamWriter("HistoryPath.cache", false);
            foreach (string  item in historyPath)
            {
                sw.WriteLine(item);
            }
            sw.Close();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveHistoryPath();
        }
    }

    public class PDFResult
    {
        public string FilePath;
        public bool IsOpen;
        public PDFResult(string path, bool ok)
        {
            FilePath = path;
            IsOpen = ok;
        }
    }
}
